home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / rsynth1.zip / aufile.c < prev    next >
C/C++ Source or Header  |  1994-11-01  |  4KB  |  210 lines

  1. #include <config.h>
  2. #include "proto.h"
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <useconfig.h>
  6. #include "getargs.h"
  7. #include "l2u.h"
  8. #include "hplay.h"
  9. #include "file.h"
  10.  
  11. #define SUN_MAGIC     0x2e736e64        /* Really '.snd' */
  12. #define SUN_HDRSIZE    24            /* Size of minimal header */
  13. #define SUN_UNSPEC    ((unsigned)(~0))    /* Unspecified data size */
  14. #define SUN_ULAW    1            /* u-law encoding */
  15. #define SUN_LIN_8    2            /* Linear 8 bits */
  16. #define SUN_LIN_16    3            /* Linear 16 bits */
  17.  
  18. file_write_p file_write = NULL;
  19. file_term_p  file_term  = NULL;
  20.  
  21. static char *linear_file;
  22. static char *au_file;
  23. static int au_fd = -1;            /* file descriptor for .au ulaw file */
  24. static int linear_fd = -1;
  25.  
  26. static unsigned au_encoding = SUN_ULAW;
  27. static unsigned au_size = 0;
  28.  
  29. static void wblong PROTO((int fd, unsigned long x));
  30. static void 
  31. wblong(fd, x)
  32. int fd;
  33. unsigned long x;
  34. {
  35.  int i;
  36.  for (i = 24; i >= 0; i -= 8)
  37.   {
  38.    char byte = (char) ((x >> i) & 0xFF);
  39.    write(fd, &byte, 1);
  40.   }
  41. }
  42.  
  43. extern void au_header PROTO((int fd,unsigned enc,unsigned rate,unsigned size,char *comment));
  44.  
  45. void 
  46. au_header(fd, enc, rate, size, comment)
  47. int fd;
  48. unsigned enc;
  49. unsigned rate;
  50. unsigned size;
  51. char *comment;
  52. {
  53.  if (!comment)
  54.   comment = "";
  55.  wblong(fd, SUN_MAGIC);
  56.  wblong(fd, SUN_HDRSIZE + strlen(comment));
  57.  wblong(fd, size);
  58.  wblong(fd, enc);
  59.  wblong(fd, rate);
  60.  wblong(fd, 1);                   /* channels */
  61.  write(fd, comment, strlen(comment));
  62. }
  63.  
  64. static void aufile_write PROTO((int n,short *data));
  65.  
  66. static void
  67. aufile_write(n, data)
  68. int n;
  69. short *data;
  70. {
  71.  if (n > 0)
  72.   {
  73.    if (linear_fd >= 0)
  74.     {
  75.      unsigned size = n * sizeof(short);
  76.      if (write(linear_fd, data, n * sizeof(short)) != size)
  77.             perror("write");
  78.     }
  79.    if (au_fd >= 0)
  80.     {
  81.      if (au_encoding == SUN_LIN_16)
  82.       {
  83.        unsigned size = n * sizeof(short);
  84.        if (write(au_fd, data, size) != size)
  85.         perror("write");
  86.        else
  87.         au_size += size;
  88.       }
  89.      else if (au_encoding == SUN_ULAW)
  90.       {
  91.        unsigned char *plabuf = (unsigned char *) malloc(n);
  92.        if (plabuf)
  93.         {
  94.          unsigned char *p = plabuf;
  95.          unsigned char *e = p + n;
  96.          while (p < e)
  97.           {
  98.            *p++ = short2ulaw(*data++);
  99.           }
  100.          if (write(au_fd, plabuf, n) != n)
  101.           perror(au_file);
  102.          else
  103.           au_size += n;
  104.          free(plabuf);
  105.         }
  106.        else
  107.         {
  108.          fprintf(stderr, "%s : No memory for ulaw data\n", program);
  109.         }
  110.       }
  111.      else
  112.       {
  113.        abort();
  114.       }
  115.     }
  116.   }
  117. }
  118.  
  119. static void aufile_term PROTO((void));
  120.  
  121. static void
  122. aufile_term()
  123. {
  124.  /* Finish ulaw file */
  125.  if (au_fd >= 0)
  126.   {
  127.    off_t here = lseek(au_fd, 0L, SEEK_CUR);
  128.    if (here >= 0)
  129.     {
  130.      /* can seek this file - truncate it */
  131.      ftruncate(au_fd, here);
  132.      /* Now go back and overwite header with actual size */
  133.      if (lseek(au_fd, 8L, SEEK_SET) == 8)
  134.       {
  135.        wblong(au_fd, au_size);
  136.       }
  137.     }
  138.    if (au_fd != 1)
  139.     close(au_fd);
  140.    au_fd = -1;
  141.   }
  142.  /* Finish linear file */
  143.  if (linear_fd >= 0)
  144.   {
  145.    ftruncate(linear_fd, lseek(linear_fd, 0L, SEEK_CUR));
  146.    if (linear_fd != 1)
  147.     close(linear_fd);
  148.    linear_fd = -1;
  149.   }
  150. }
  151.  
  152.  
  153. int
  154. file_init(argc, argv)
  155. int argc;
  156. char *argv[];
  157. {
  158.  argc = getargs("File output", argc, argv,
  159.                 "l", "", &linear_file, "Raw 16-bit linear pathname",
  160.                 "o", "", &au_file,     "Sun/Next audio file name",
  161.                 NULL);
  162.  if (help_only)
  163.   return argc;
  164.  
  165.  if (au_file)
  166.   {
  167.    if (strcmp(au_file, "-") == 0)
  168.     {
  169.      au_fd = 1;                   /* stdout */
  170.     }
  171.    else
  172.     {
  173.      au_fd = open(au_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  174.      if (au_fd < 0)
  175.       perror(au_file);
  176.     }
  177.    if (au_fd >= 0)
  178.     {
  179.      if (samp_rate > 8000)
  180.       au_encoding = SUN_LIN_16;
  181.      else
  182.       au_encoding = SUN_ULAW;
  183.      au_header(au_fd, au_encoding, samp_rate, SUN_UNSPEC, "");
  184.      au_size = 0;
  185.     }
  186.   }
  187.  
  188.  if (linear_file)
  189.   {
  190.    if (strcmp(linear_file, "-") == 0)
  191.     {
  192.      linear_fd = 1 /* stdout */ ;
  193.     }
  194.    else
  195.     {
  196.      linear_fd = open(linear_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  197.      if (linear_fd < 0)
  198.       perror(linear_file);
  199.     }
  200.   }
  201.  if (au_fd >= 0 || linear_fd >= 0)
  202.   {
  203.    file_write = aufile_write;
  204.    file_term  = aufile_term;
  205.   }
  206.  return argc;
  207. }
  208.  
  209.  
  210.